package com.jinyijia.api.rest.v1;

import com.alibaba.fastjson.JSONObject;
import com.jinyijia.api.infrastructure.UserInfoManager;
import com.jinyijia.api.rest.v1.order.dto.OrderDTO;
import com.jinyijia.api.rest.v1.payinfo.dto.PayInfoDTO;
import com.jinyijia.api.rest.v1.payinfo.dto.PaymentInfoDTO;
import com.jinyijia.api.rest.v1.payinfo.vo.BankInfoVo;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lhw
 * @date 2018/8/16
 **/
@RestController
@RequestMapping("pay-info")
public class PayInfoController {

    @Autowired
    @LoadBalanced
    private RestTemplate restTemplate;

    private static final Logger logger = Logger.getLogger(PayInfoController.class);

    @GetMapping
    public List<BankInfoVo> bankInfoVo(String[] codes) {
        List<OrderDTO> orderDTOS = Arrays.asList(codes).stream().map(code -> {
            JSONObject orders = restTemplate.getForObject("http://order-service/orders?code={1}&customInfo.id={2}", JSONObject.class, code, UserInfoManager.getCurrentUserId());
            return orders.getJSONArray("content").toJavaList(OrderDTO.class).get(0);
        }).collect(Collectors.toList());
        List<BankInfoVo> bankInfoVos = new ArrayList<>();
        for (int i = 0; i < orderDTOS.size(); i++) {
            OrderDTO orderDTO = orderDTOS.get(i);
            BankInfoVo bankInfoVo;
            switch (orderDTO.getShopInfo().getId()) {
                case "11":
                    bankInfoVo = new BankInfoVo(orderDTO.getShopInfo().getName(), "刘佳", "齐鲁朝山街支行", "622 3795 3157 0007 0827", orderDTO.getCode(), orderDTO.getAmount().doubleValue() / 100, "银行转账", UserInfoManager.getCurrentUsername(), "");
                    break;
                case "12":
                    bankInfoVo = new BankInfoVo(orderDTO.getShopInfo().getName(), "徐桂琴", "农业银行济南银河支行", "6228 4902 5800 3392 570", orderDTO.getCode(), orderDTO.getAmount().doubleValue() / 100, "银行转账", UserInfoManager.getCurrentUsername(), "");
                    break;
                case "13":
                    bankInfoVo = new BankInfoVo(orderDTO.getShopInfo().getName(), "刘佳", "中国银行济南府东支行", "6013 8211 0001 3303 369", orderDTO.getCode(), orderDTO.getAmount().doubleValue() / 100, "银行转账", UserInfoManager.getCurrentUsername(), "");
                    break;
                default:
                    bankInfoVo = new BankInfoVo(orderDTO.getShopInfo().getName(), "你的名字" + i * 2, "农业银行", "622 6222 1234 2345 1265", orderDTO.getCode(), orderDTO.getAmount().doubleValue() / 100, "银行转账", UserInfoManager.getCurrentUsername(), "");
            }
            bankInfoVos.add(bankInfoVo);
        }
        return bankInfoVos;
    }

    @PostMapping
    public ResponseEntity save(@RequestBody List<PayInfoDTO> payInfoDTOS) {
        List<String> orderNums = new ArrayList<>();
        payInfoDTOS.forEach(payInfoDTO -> {
            try {
                String orderNum = payInfoDTO.getOrderCode();
                JSONObject orders = restTemplate.getForObject("http://order-service/orders?code={1}&customInfo.id={2}", JSONObject.class, payInfoDTO.getOrderCode(), UserInfoManager.getCurrentUserId());
                OrderDTO orderDTO = orders.getJSONArray("content").toJavaList(OrderDTO.class).get(0);
                payInfoDTO.setStatus(0);
                payInfoDTO.setPayCode(getPayNumber());
                payInfoDTO.setRequestTime(new Date());
                payInfoDTO.setAmount(orderDTO.getAmount());
                payInfoDTO.setShopName(orderDTO.getShopInfo().getName());
                payInfoDTO.setBuyerName(orderDTO.getCustomInfo().getName());
                payInfoDTO.setUserId(UserInfoManager.getCurrentUserId());
                payInfoDTO.setReceipts(orderDTO.getAmount());

                orderNums.add(orderNum);
                JSONObject result = restTemplate.postForObject("http://pay-service/payments", payInfoDTO, JSONObject.class);
                if (result.getInteger("id") > 0) {
                    // 支付后直接推送管家婆
                    callback(toPaymentInfoDTO(result));
                    //通知订单修改状态: 支付待审核
                    updateOrderStatus(orderNums);
                }
            } catch (Exception e) {
                logger.error("支付订单异常:" + e.getMessage());
            }
        });
        return ResponseEntity.ok().build();
    }

    /**
     * 获取支付单号
     *
     * @return
     */
    private synchronized String getPayNumber() {
        StringBuffer payNumber = new StringBuffer();
        payNumber.append("Z");
        String time = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
        payNumber.append(time);
        int num = (int) ((Math.random() * 9 + 1) * 1000);
        payNumber.append(num);
        return payNumber.toString();
    }

    /**
     * 通知订单修改状态: 支付待审核
     */
    private void updateOrderStatus(List<String> orderNums) {
        try {
            for (String orderNum : orderNums) {
                String url = "http://order-service/orders/" + orderNum + "/PART_REVIEW";
                restTemplate.put(url, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private PaymentInfoDTO toPaymentInfoDTO(JSONObject jsonObject){
        return new PaymentInfoDTO(jsonObject.getString("payCode"),jsonObject.getString("amount"),jsonObject.getDate("requestTime"),jsonObject.getString("type"), Collections.singleton(new com.jinyijia.api.rest.v1.payinfo.dto.OrderDTO(jsonObject.getString("orderCode"))));
    }

    /**
     * 支付回调
     */
    private void callback(PaymentInfoDTO paymentInfoDTO) {
        try {
            String url = "http://order-service/orders/pay/success";
            logger.debug(paymentInfoDTO.toString());
            restTemplate.postForEntity(url, paymentInfoDTO, Object.class);
        } catch (Exception e) {
        }
    }
}
